/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-22     hehung       the first version
 */

#include "app_key.h"
#include "board.h"

typedef struct
{
    uint8_t Key1;
    uint8_t Key2;
    uint8_t Key3;
} S_key_pin;

typedef struct
{
    uint8_t m_filter_cnt;
    E_KeySt m_status;
    uint8_t m_key_pin_st;
} S_KeyStatusStr;

S_key_pin Key_pin;
S_KeyStatusStr Key_Status[KEY_NUM];
E_KeySt key_Pressed[KEY_NUM] = {KEY_UNKNOW, KEY_UNKNOW, KEY_UNKNOW};
uint16_t key_pressed_counter[KEY_NUM] = {0, 0, 0};


static void KEY_ReadKeyLevel(void);
static void KEY_KeySwFilterCounting(S_KeyStatusStr *paraKeySta);
static void KEY_KeySwFilter(void);
static void KEY_ManageEntry(void *parameter);
static void KEY_ThreadManage(void);
static void KEY_JudgeKeyPressed(void);


void KEY_AppInit(void)
{
    uint8_t i = 0u;

    Key_pin.Key1 = rt_pin_get("PF.1");
    Key_pin.Key2 = rt_pin_get("PF.0");
    Key_pin.Key3 = rt_pin_get("PA.2");

    rt_pin_mode(Key_pin.Key1, PIN_MODE_INPUT);
    rt_pin_mode(Key_pin.Key2, PIN_MODE_INPUT);
    rt_pin_mode(Key_pin.Key3, PIN_MODE_INPUT);

    for(i=0; i<KEY_NUM; i++)
    {
        Key_Status[i].m_filter_cnt = 0u;
        Key_Status[i].m_key_pin_st = 0u;
        Key_Status[i].m_status = KEY_UNKNOW;
    }

    KEY_ThreadManage();
}

E_KeySt KEY_GetKeyStatus(uint8_t paraKeyNum)
{
    return Key_Status[paraKeyNum].m_status;
}

E_KeySt KEY_GetKeyPressedStatus(uint8_t paraKeyNum)
{
    return key_Pressed[paraKeyNum];
}


static void KEY_ReadKeyLevel(void)
{
    Key_Status[KEY_NUM_1].m_key_pin_st = (uint8_t)rt_pin_read(Key_pin.Key1);
    Key_Status[KEY_NUM_2].m_key_pin_st = (uint8_t)rt_pin_read(Key_pin.Key2);
    Key_Status[KEY_NUM_3].m_key_pin_st = (uint8_t)rt_pin_read(Key_pin.Key3);
}

static void KEY_KeySwFilterCounting(S_KeyStatusStr *paraKeySta)
{
    if(0u == paraKeySta->m_key_pin_st)
    {
        if(paraKeySta->m_filter_cnt >= KEY_SW_FILTER_THD)
        {
            paraKeySta->m_status = KEY_PRESSED;
        }
        else
        {
            paraKeySta->m_filter_cnt ++;
        }
    }
    else
    {
        paraKeySta->m_filter_cnt = 0u;
        paraKeySta->m_status = KEY_RELEASED;
    }
}

static void KEY_KeySwFilter(void)
{
    KEY_KeySwFilterCounting(&Key_Status[KEY_NUM_1]);
    KEY_KeySwFilterCounting(&Key_Status[KEY_NUM_2]);
    KEY_KeySwFilterCounting(&Key_Status[KEY_NUM_3]);
}

static void KEY_JudgeKeyPressed(void)
{
    uint8_t i = 0u;
    static E_KeySt Last_KeyStatus[KEY_NUM] = {KEY_UNKNOW, KEY_UNKNOW, KEY_UNKNOW};

    for(i=0u; i<KEY_NUM; i++)
    {
        /*Key pressed this cycle*/
        if((KEY_PRESSED == KEY_GetKeyStatus(i))
            && (KEY_RELEASED == Last_KeyStatus[i]))
        {
            key_Pressed[i] = KEY_PRESSED;
            key_pressed_counter[i] = 0u;
            rt_kprintf("KEY: Key %d Pressed\n", i);

        }
        else if((KEY_RELEASED == KEY_GetKeyStatus(i))
            && (KEY_PRESSED == Last_KeyStatus[i]))
        {
            key_Pressed[i] = KEY_RELEASED;
            rt_kprintf("KEY: Key %d Released\n", i);
            rt_kprintf("KEY: Hold Key for %d ms\n", key_pressed_counter[i]*10);
        }
        else if((KEY_PRESSED == KEY_GetKeyStatus(i))
            && (KEY_PRESSED == Last_KeyStatus[i]))
        {
            key_pressed_counter[i] ++;
        }

        Last_KeyStatus[i] = KEY_GetKeyStatus(i);
    }
}

static void KEY_ManageEntry(void *parameter)
{
    while(1)
    {
        KEY_ReadKeyLevel();
        KEY_KeySwFilter();
        KEY_JudgeKeyPressed();
        rt_thread_mdelay(10);
    }
}

static void KEY_ThreadManage(void)
{
    rt_thread_t key_thread;

    key_thread = rt_thread_create("KEY Thread Manage",     /*线程名字*/
                                   KEY_ManageEntry,/*线程入口函数*/
                                   RT_NULL, /*线程入口函数参数*/
                                   2048,    /*线程栈大小*/
                                   5,       /*线程优先级*/
                                   10);     /*线程时间片*/

    if(key_thread != RT_NULL)
    {
        rt_kprintf("KEY Thread Created Success!\n");
        rt_thread_startup (key_thread);
    }
    else
    {
        rt_kprintf("KEY Thread Create Failed!\n");
    }
}
